

/*
 通过ProgressID找到对应的MailUploadFile对象中的文件索引，用于删除
 */
function getMailUploadIndex(PId){
    var len = mailUploadFile.FILES_INFOS.length;
    if (len > 0) {
        for (var i = 0; i < len; i++) {
            if (mailUploadFile.FILES_INFOS[i].progress_id == PId) {
                return i;
            }
        }
    }
}


var ResumeUpload = Class.create();
ResumeUpload.prototype = {
    initialize: function(options){
        this._blob = null;
        this._file_index = 0;
        this._file_count = 0;
        this._offset = null;
        this._slice = 50000;
        this._headerstr = '';
        this._outstr = '';
        this._cancelFlag = 0;
        this._C_request = null;
        this._Urequest = null;
        this._filelength = 0;
        this._filename = '';
        this.options = {
            url: '',
            userid: UserSohuID,
            filelists: null,
            //片成功/失败时候的事件
            //成功了就绘图，失败了，根据原因，选择是重试还是通知服务器删除
            onSliceSuccess: function(ret){
            },
            onSliceFailed: function(ret){
            },
            //单个文件成功/失败时候的事件
            //成功了就将显示的域换种表现形式，失败了，根据原因，选择重试还是通知服务器删除现有的
            onSuccess: function(ret){
            },
            onFailed: function(ret){
            },
            //请求文件状态
            //主要是用在第一次绘图的时候，可以查询下服务器上的文件状态
            onRequestSuccess: function(ret){
            },
            onRequestFailed: function(ret){
            },
            //初始化成功事件
            //初始化主要是为文件分配一个用于标识的随机号
            onInitSuccess: function(ret){
            },
            //检查Gears的事件
            //暂时没用
            onRemoveFailed: function(ret){
            },
            onRemoveSuccess: function(ret){
            },
            //加入队列成功/失败事件
            onEnQueueSuccess: function(ret){
            },
            onEnQueueFailed: function(ret){
            },
            //总体成功的事件
            //暂时没用
            onTotalSuccess: function(ret){
            }
        };
        Object.extend(this.options, options ||
        {});
    },
    
    createFilePID: function(name, length){
        var m = base64.encode64(name + length);
        var t = hex_md5(m);
        return t.toLowerCase();
    },
    initCheck: function(){
        if (this.options.url == '' ||
        this.options.filelists == null) {
            // alert( "参数错误" );
            _dialog.alert({
                info: '参数错误'
            });
            return;
        }
        var f_len = this.options.filelists.length;
        for (var i = 0; i < f_len; ++i) {
            this.options.filelists[i].id = this.createFilePID(this.options.filelists[i].name, this.options.filelists[i].blob.length);
        }
        this._dispatch(this.options.onInitSuccess, this.options.filelists);
        this._file_count = this.options.filelists.length;
        this._startControl();
    },
    _singleSuccess: function(){
        if (this._file_index < this._file_count) 
            this._startControl();
        else 
            mailUploadFile.uploading = false;
        return;
    },
    _encodeFileName: function(fileName){
        return encodeURIComponent(fileName);
    },
    _startControl: function(){
        try {
            if (getMailUploadIndex(this.options.filelists[this._file_index].id) >= 0) {
                this._file_index++;
                this._singleSuccess();
            }
            this._blob = this.options.filelists[this._file_index].blob;
            this._filename = this._encodeFileName(this.options.filelists[this._file_index].name);
            this._filelength = this._blob.length;
            this._FileStatus_check();
        } 
        catch (m) {
            if (this._file_index < this._file_count) {
                this._singleSuccess();
            }
            else {
                mailUploadFile.uploading = false;
                return;
            }
        }
    },
    
    _dispatch: function(thing, para){
        thing(para);
    },
    
    resume: function(){
        if (this._file_index >= this._file_count) {
            return;
        }
        if (this.isCancelled()) 
            this.cancelFlag = 0;
        this._startControl();
    },
    _postUrl: function(seek){
        return this.options.url + "?xid=" + this.options.filelists[this._file_index].id + "&seek=" + seek;
    },
    
    _getUrl: function(act, index, fileLen){
        var retUrl = '';
        var xid = null;
        if (index == null) {
            xid = this._file_index;
            if (this._file_index < 0) 
                xid = 0;
        }
        else {
            xid = Number(this._getIndex(index));
        }
        retUrl = this.options.url + "?xid=" + this.options.filelists[xid].id + "&act=" + act + "&FName=" + this.options.filelists[xid].name;
        if (fileLen != null) {
            retUrl = retUrl + "&filesize=" + fileLen;
        }
        return retUrl;
    },
    
    _FileStatus_check: function(PId){
        this._C_request = google.gears.factory.create('beta.httprequest');
        if (PId == null || PId == undefined) {
            //这时候是默认的检查
            this._C_request.open('GET', this._getUrl('check'));
        }
        else {
            //这时候检查指定PId的文件，在本地和服务器的大小是否一致
            var index = this._getIndex(PId);
            var len_check = this.options.filelists[index].blob.length;
            //var urlID = encodeURIComponent( PId );
            this._C_request.open('GET', this._getUrl('fileRecheck', PId, len_check));
        }
        
        this._C_request.send();
        
        this._C_request.onreadystatechange = function(){
            if (this._C_request.readyState == 4 && (this._C_request.status >= 200 && this._C_request.status < 300)) {
                var res = (this._C_request.responseText.evalJSON()).evalJSON();
                if (res) {
                    if (Boolean(res.success) == true) {
                        if (PId == null || PId == undefined) {
                            var ret = Object;
                            ret.offset = res.size;
                            ret.filename = this._filename;
                            ret.filelength = this._filelength;
                            ret.id = this.options.filelists[this._file_index].id;
                            this._offset = Number(res.size);
                            this._dispatch(this.options.onRequestSuccess, ret);
                            if (this._offset < this._filelength) {
                                if (!this.isCancelled()) 
                                    this._FileBlob_Upload();
                                else 
                                    return;
                            }
                            else {
                                this._FileStatus_check(ret.id);
                            }
                        }
                        else {
                            var ret = Object;
                            this._dispatch(this.options.onSingleSuccess, res);
                            this._file_index++;
                            this._singleSuccess();
                        }
                    }
                    else {
                        this.dispatch(this.options.onFailed);
                    }
                }
            }
            else {
                setTimeout("this.resume", 3000);
            }
        }
.bind(this);
    },
    _FileBlob_Upload: function(PId){
        this._Urequest = google.gears.factory.create('beta.httprequest');
        this._Urequest.open('POST', this._postUrl(this._offset));
        this._Urequest.setRequestHeader('Content-Type', 'multipart/form-data;');
        
        var slicelength = this._slice;
        if ((this._offset + this._slice) > this._filelength) {
            slicelength = this._filelength - this._offset;
        }
        var upload_b = this._blob.slice(this._offset, slicelength);
        try {
            this._Urequest.send(upload_b);
            this._Urequest.onreadystatechange = function(){
                if (this._Urequest.readyState == 4 && this._Urequest.status == 200) {
                    if (this.isCancelled()) 
                        return;
                    try {
                    
                        var res_tmp = this._Urequest.responseText.evalJSON();
                        var res = res_tmp.evalJSON();
                        delete res_tmp;
                    } 
                    catch (e) {
                        // alert( e );
                        _dialog.alert({
                            info: e
                        });
                        //此处应当重传或者退出程序
                    }
                    if (res) {
                        if (Boolean(res.success) == true) {
                            this._offset = res.file_size;
                            var ret = Object;
                            ret.offset = this._offset;
                            ret.filename = this._filename;
                            ret.filelength = this._filelength;
                            ret.id = this.options.filelists[this._file_index].id;
                            this._dispatch(this.options.onSliceSuccess, ret);
                            if (this._offset < this._filelength) {
                                this._FileBlob_Upload();
                            }
                            else {
                                this._FileStatus_check(ret.id);
                            }
                        }
                        else {
                            var ret;
                            this._dispatch(this.options.onSliceFailed, ret);
                        }
                    }
                }
                else {
                    setTimeout("this.resume", 3000);
                }
            }
.bind(this);
        } 
        catch (e) {
            return;
        }
    },
    
    enQueue: function(files){
        if (files.length > 0) {
            this.abort();
            var ret = [];
            //这里要修改一下，给他分配一个新的随机ID
            for (var q = 0; q < files.length; ++q) {
                var tmp = files[q];
                tmp.id = this.createFilePID(files[q].name, files[q].blob.length);//mailUploadFile.createRandom();
                ret.push(tmp);
                this.options.filelists = this.options.filelists.concat(files[q]);
                this._file_count += 1;
            }
            this._dispatch(this.options.onEnQueueSuccess, ret);
            //			this.resume();
        }
    },
    _deleteServer: function(PId, index){
        var del_request = google.gears.factory.create('beta.httprequest');
        del_request.open('GET', this._getUrl('del', PId));
        del_request.send();
        del_request.onreadystatechange = function(){
            var that = RUpload.getThis();
            if (del_request.readyState == 4 && del_request.status == 200) {
                try {
                    var res = (del_request.responseText.evalJSON()).evalJSON();
                    if (Boolean(res.success) == true) {
                        that.uploader.options.filelists.splice(index, 1);
                        that.uploader._file_count--;
                        that.uploader._file_index--;
                        if (that.uploader._file_count < 0) 
                            that.uploader._file_count = 0;
                        if (that.uploader._file_index < 0) 
                            that.uploader._file_index = 0;
                        that.uploader._dispatch(that.uploader.options.onRemoveSuccess, PId);
                        return true;
                    }
                    else {
                        that.uploader._dispatch(that.uploader.options.onRemoveFailed, PId);
                        return false;
                    }
                } 
                catch (e) {
                    // alert( e );
                    _dialog.alert({
                        info: e
                    });
                    return false;
                }
            }
        }
    },
    cancelUpload: function(ret){
        this.cancelFlag = 1;
        try {
            mailUpladFile.uploading = false;
        } catch (e) {}
    },
    isCancelled: function(){
        return this.cancelFlag == 1 ? (function(){
			try {
            	mailUpladFile.uploading = false;
        	} catch (e) {}
			return true;
		})() : false;
    },
    removeFromList: function(PId, cancelFlag){
		
		try {
			this.abort();
			var index = this._getIndex(PId);
		} catch(e) {}
		try {
        	var _cancel = 0;
            if (cancelFlag == 1) 
                _cancel = 1;
        } 
        catch (e) {
        }
		try {
			if (_cancel == 1) {
				if (this._Urequest == null) {
					var _d_index = getMailUploadIndex(PId);
					if (_d_index >= 0) 
						mailUploadFile.FILES_INFOS.splice(_d_index, 1);
					this._file_index++;
					this.cancelUpload(index);
					this.cancelFlag = 0;
					this.resume();
				}
				else {
					var self = this;
					setTimeout(function(){
						self.abort();
					}, 500);
				}
			}
		} catch(e) {}
        //this.abort();
		try {
			if (index <= this._file_index) {
				if (Boolean(this._deleteServer(PId, index)) == true) {
					this._dispatch(this.options.onRemoveSuccess, PId);
				}
				else {
					this._dispatch(this.options.onRemoveFailed, PId);
				}
			}
		} catch(e) {}
		try {
			if (index > this._file_index) {
				this.options.filelists.splice(index, 1);
				this._file_count--;
				this._dispatch(this.options.onRemoveSuccess, PId);
			}
		} catch(e) {}
		try {
			mailUploadFile.uploading = false;
        } catch (e) { }
    },
    
    abort: function(){
        var flag = 0;
        try {
            if (this._C_request != null) {
                this._C_request.abort();
            }
            if (this._Urequest != null) {
                this._Urequest.abort();
                if (this._Urequest.readyState != 0) 
                    flag = 1;
            }
            try {
                if (this._Urequest.readyState != 0) 
                    flag = 1;
            } 
            catch (e) {
                // alert( e );
                _dialog.alert({
                    info: e
                });
            }
            try {
                if (this._C_request.readyState != 0) 
                    flag = 1;
            } 
            catch (e) {
                // alert( e );
                _dialog.alert({
                    info: e
                });
            }
            if (flag == 1) 
                setTimeout("this.abort", 100);
        } 
        catch (E) {
            // alert( E );
            _dialog.alert({
                info: E
            });
        }
    },
    
    
    //    pause : function( PId ){
    //
    //
    //            },
    _getIndex: function(PId){
        var list = this.options.filelists.clone();
        //var list =  RUpload.uploader.options.filelists;
        var len = list.length;
        for (var i = 0; i < len; ++i) {
            if (list[i].id == PId) {
                return i;
            }
        }
    }
};



var GearsUploader = Class.create();
GearsUploader.prototype = {
    initialize: function(){
        this._is_init = 0;
        this._desktop = null;
        this.uploader = null;
        this._FileLists = [];
        this._total_length = 10 * 1024 * 1024;
    },
    getThis: function(){
        return this;
    },
    init: function(){
        if (!window.google || !google.gears) {
            return;
        }
        else {
            //                       if ( this._desktop == null )
            if (this._is_init == 0) {
                try {
                    this._desktop = google.gears.factory.create('beta.desktop');
                    this._is_init = 1;
                } 
                catch (e) {
                }
            }
            try {
                $('gears_notify').update("");
            } 
            catch (e) {
            }
            try {
                $('upload_iframe_content').update("");
                $('upload_pointer').update("<span style='cursor:pointer;' onclick='RUpload._desktop.openFiles( RUpload._on_select );'>添加附件</span><span style='color:#666666;'> ( 可上传10M )</span>");
            } 
            catch (e) {
            }
        }
        this._is_init = 0;
        //this._desktop = null;
        this.uploader = null;
        this._FileLists = [];
        mailUploadFile.init();
        return true;
    },
    _getIndex: function(PId){
        var that = RUpload.getThis();
        var len = that._FileLists.length;
        for (var i = 0; i < len; ++i) {
            if (that._FileLists[i].fid == PId) {
                return i;
            }
        }
    },
    _singleSuccess: function(ret){
        var that = RUpload.getThis();
        try {
            var index = that._getIndex(ret.fid);
            that._FileLists[index].success = true;
            $('file_upload_info_' + that._FileLists[index].fid).update('<dd>' + that._FileLists[index].filename + ' <b id="file_upload_size_' + that._FileLists[index].fid + '"> (' + strfsize(that._FileLists[index].size) + ') <a hidefocus="true" href="javascript:;" onclick="RUpload.deleteUpload(\'' + that._FileLists[index].fid + '\', \'' + that._FileLists[index].fid + '\');return false;" id="file_upload_delete_' + that._FileLists[index].fid + '"> 删除 </a>, </b></dd>');
            var obj = new Object();
            obj.success = true;
            obj.filename = that._FileLists[index].filename;
            obj.size = that._FileLists[index].size;
            obj.type = ret.type;
            obj.id = ret.id;//that._FileLists[ index ].progress_id;
            obj.fid = that._FileLists[index].progress_id;
            obj.progress_id = that._FileLists[index].progress_id;
            mailUploadFile.FILES_INFOS.push(obj);
            //that.uploader.resume();
        } 
        catch (E) {
            _dialog.alert({
                info: E
            });
        }
    },
    _createForm: function(ret){
        var obj = [];
        var ret_len = ret.length;
        for (var i = 0; i < ret_len; ++i) {
            var fileInfo = {
                fid: ret[i].id,
                filename: ret[i].name,
                success: false,
                size: ret[i].blob.length,
                type: 'application/octet-stream',
                id: i,
                progress_id: ret[i].id
            };
            this.RUpload._FileLists.push(fileInfo);
            var fileInfos = '<dl id="file_upload_info_' + fileInfo.fid + '" style="white-space:nowrap;margin:0px 0px 0px 0px;"><dd>' +
            '<table collspacing=0 collpadding=0 border=0><tbody><tr>' +
            '<td>' +
            fileInfo.filename +
            '</td>' +
            '<td><div style="width:300px;height:8px;font-size:0pt;border:1px solid #F5AA69;margin:8px auto;"><div id="upload_progress_' +
            fileInfo.fid +
            '" style="background:#FFBD4B url(\'' +
            MailConst.ALL +
            '/pic_rate.gif\') repeat-x;height:100%;width:0%;"></div></div></td>'            //                              + '<td><a hidefocus="true" href="javascript:;" onclick="RUpload.PauseUpload(\''+ fileInfo.fid +'\');return false;" id="file_upload_pause_'+ fileInfo.fid +'"> 暂停 </a>, </td>'
            +
            '<td><a hidefocus="true" href="javascript:;" onclick="RUpload.cancelUpload(\'' +
            fileInfo.fid +
            '\');return false;" id="file_upload_delete_' +
            fileInfo.fid +
            '"> 取消 </a>, </td>' +
            '</tr></tbody></table></dd></dl>';
            if ($('file_upload_info_' + fileInfo.progress_id)) {
                Element.remove($('file_upload_info_' + fileInfo.progress_id));
            }
            Element.insert($('uploadInfoDIV'), {
                bottom: fileInfos
            });
            $('uploadInfoDIV').show();
        }
        return;
    },
    _enQueueSuccess: function(ret){
        var obj = [];
        var ret_len = ret.length;
        for (var i = 0; i < ret_len; ++i) {
            var fileInfo = {
                fid: ret[i].id,
                filename: ret[i].name,
                success: false,
                size: ret[i].blob.length,
                //由于没法生成form，此处没办法得到精确的类型，只好暂时先用octet-stream代替
                type: 'application/octet-stream',
                id: i,
                progress_id: ret[i].id
            };
            this.RUpload._FileLists.push(fileInfo);
            var fileInfos = '<dl id="file_upload_info_' + fileInfo.fid + '" style="white-space:nowrap;margin:0px 0px 0px 0px;"><dd>' +
            '<table collspacing=0 collpadding=0 border=0><tbody><tr>' +
            '<td>' +
            fileInfo.filename +
            '</td>' +
            '<td><div style="width:300px;height:8px;font-size:0pt;border:1px solid #F5AA69;margin:8px auto;"><div id="upload_progress_' +
            fileInfo.fid +
            '" style="background:#FFBD4B url(\'' +
            MailConst.ALL +
            '/pic_rate.gif\') repeat-x;height:100%;width:0%;"></div></div></td>' +
            '<td><a hidefocus="true" href="javascript:;" onclick="RUpload.cancelUpload(\'' +
            fileInfo.fid +
            '\');return false;" id="file_upload_delete_' +
            fileInfo.fid +
            '"> 取消 </a>, </td>' +
            '</tr></tbody></table></dd></dl>';
            if ($('file_upload_info_' + fileInfo.progress_id)) {
                Element.remove($('file_upload_info_' + fileInfo.progress_id));
            }
            Element.insert($('uploadInfoDIV'), {
                bottom: fileInfos
            });
        }
        //                      RUpload.uploader._file_index ++;
        RUpload.uploader.resume();
    },
    
    //    PauseUpload : function( id ){
    //                      if( this.uploader == null ){
    //                          return;
    //                      }
    //                      else
    //                      {
    //                      }
    //                  },
    //
    deleteUpload: function(id, index){
        if (this.uploader == null) {
            return;
        }
        else {
            return this.uploader.removeFromList(index);
        }
    },
    cancelUpload: function(id, index){
        if (this.uploader == null) {
            return;
        }
        else {
            return this.uploader.removeFromList(id, 1);
        }
    },
    _removeSuccess: function(ret){
        var that = RUpload.getThis();
        var upindex = getMailUploadIndex(ret);
        if (upindex >= 0) {
            mailUploadFile.FILES_INFOS.splice(upindex, 1);
        }
        that._FileLists.splice(that._getIndex(ret), 1);
        Element.remove($('file_upload_info_' + ret));
        if (that._FileLists.length == 0) 
            $('uploadInfoDIV').style.display = 'none';
        that.uploader.resume();
    },
    _removeFailed: function(ret){
    },
    _totalSuccess: function(ret){
        mailUpladFile.uploading = false;
    },
    _SliceSuccess: function(ret){
        var w = parseInt((ret.offset * 100) / ret.filelength);
        if (w > parseInt($('upload_progress_' + ret.id).style.width)) {
            Element.setStyle($('upload_progress_' + ret.id), {
                width: w + "%"
            });
        }
    },
    _on_select: function(files){
        if (files.length == 0) 
            return false;
        var that = RUpload.getThis();
        if (that._totalSizeCheck(files) == false) 
            return false;
        $('uploadInfoDIV').style.display = '';
        if (that.uploader == null) {
            var options = {
                url: 'mail/att/resumeUpload',
                filelists: files,
                onSliceSuccess: that._SliceSuccess,
                onSuccess: that._totalSuccess,
                onRemoveFailed: that._removeFailed,
                onRequestSuccess: that._requestSuccess,
                onRemoveSuccess: that._removeSuccess,
                onInitSuccess: that._createForm,
                onSingleSuccess: that._singleSuccess,
                onEnQueueSuccess: that._enQueueSuccess
            };
            mailUploadFile.uploading = true;
            that.uploader = new ResumeUpload(options);
            that.uploader.initCheck();
        }
        else {
            that.uploader.enQueue(files);
            //                        that.uploader.resume();
        }
    },
    _totalSizeCheck: function(Files){
        var filterName = ["cmd", "cpl", "exe", "hta", "pif", "scr", "vbs", "vsd"];
        var len = Files.length;
        var tmpname = '';
        var total = 0;
        for (var q = 0; q < this._FileLists.length; ++q) {
            total += this._FileLists[q].size;
        }
        for (var i = 0; i < len; ++i) {
            tmpname = Files[i].name;
            if (!tmpname.blank()) {
                Files[i].name = tmpname.substring(tmpname.lastIndexOf('\\') + 1, tmpname.length);
            }
            try {
                var e = tmpname.substring(tmpname.lastIndexOf('.') + 1, tmpname.length);
                if (filterName.include(e.toLowerCase())) {
                    if (mailUploadFile.FILES_INFOS.length == 0) 
                        $('uploadInfoDIV').style.display = 'none';
                    // alert('附件不能是 "cmd", "cpl", "exe", "hta", "pif", "scr", "vbs", "vsd" 这些格式的');
                    _dialog.alert({
                        info: '附件不能是 "cmd", "cpl", "exe", "hta", "pif", "scr", "vbs", "vsd" 这些格式的'
                    });
                    return false;
                }
                if (this._FileLists.length > 0) {
                    for (var j = 0; j < this._FileLists.length; ++j) {
                        if (tmpname == this._FileLists[j].filename) {
                            if (this._FileLists.length == 0) 
                                $('uploadInfoDIV').style.display = 'none';
                            // alert('这个附件已经存在了');
                            _dialog.alert({
                                info: '这个附件已经存在了'
                            });
                            return false;
                        }
                    }
                }
            } 
            catch (E) {
            }
            total += Files[i].blob.length;
            if (total > this._total_length) {
                try {
                    if (this._FileLists.length == 0) 
                        $('uploadInfoDIV').style.display = 'none';
                } 
                catch (e) {
                }
                // alert( "您选择的文件大于10M，请重新选择" );
                _dialog.alert({
                    info: '您选择的文件大于10M，请重新选择'
                });
                return false;
            }
        }
        return true;
    },
    _requestSuccess: function(ret){
        //这个函数只会在每次断开并且重新连接的时候出现被调用的情况，用于绘画第一次请求结束时，服务器的景象
        var w = parseInt((ret.offset * 100) / ret.filelength);
        try {
            if (w > parseInt($('upload_progress_' + ret.id).style.width)) {
                Element.setStyle($('upload_progress_' + ret.id), {
                    width: w + "%"
                });
            }
        } 
        catch (e) {
        }
        
    }
};
var RUpload = new GearsUploader();
